package com.piece.core.web.util;

import com.piece.core.framework.enums.ContentType;
import com.piece.core.framework.exception.ErrorCode;
import com.piece.core.framework.exception.FrameWorkException;
import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.util.file.IoUtil;
import com.piece.core.framework.util.string.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 客户端工具类
 */
@Slf4j
public class ServletUtil {

    /**
     * 获取String参数
     */
    public static String getParameter(String name) {
        return getRequest().getParameter(name);
    }

    /**
     * 获取String参数
     */
    public static String getParameter(String name, String defaultValue) {
        return Convert.toStr(getRequest().getParameter(name), defaultValue);
    }

    public static Map<String, String> getParameter(HttpServletRequest request) {
        Map<String, String> resultMap = new HashMap<>();
        Map parameterMap = request.getParameterMap();
        Iterator<Map.Entry<String, Object>> it = parameterMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, Object> entry = it.next();
            Object value = request.getParameter(entry.getKey());
            if (value instanceof String){
                resultMap.put(entry.getKey(), value.toString());
            }
        }

        return resultMap;
    }

    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name) {
        return Convert.toInt(getRequest().getParameter(name));
    }

    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name, Integer defaultValue) {
        return Convert.toInt(getRequest().getParameter(name), defaultValue);
    }

    /**
     * 获取request
     */
    public static HttpServletRequest getRequest() {
        return getRequestAttributes().getRequest();
    }

    /**
     * 获取response
     */
    public static HttpServletResponse getResponse() {
        return getRequestAttributes().getResponse();
    }

    /**
     * 获取session
     */
    public static HttpSession getSession() {
        return getRequest().getSession(false);
    }

    public static ServletRequestAttributes getRequestAttributes() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }

    public static byte[] getBodyBytes(HttpServletRequest request) {
        try {
            return IoUtil.readBytes(request.getInputStream());
        } catch (IOException e) {
            throw new FrameWorkException(ErrorCode.ACCESS);
        }
    }

    public static String readData(HttpServletRequest request) {
        BufferedReader br = null;
        try {
            StringBuilder result = new StringBuilder();
            br = request.getReader();
            for (String line; (line = br.readLine()) != null; ) {
                if (result.length() > 0) {
                    result.append("\n");
                }
                result.append(line);
            }
            return result.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 将字符串渲染到客户端
     *
     * @param response 渲染对象
     * @param string   待渲染的字符串
     */
    public static String renderString(HttpServletResponse response, String string) {
        try {
            response.setContentType(ContentType.JSON.toString(StandardCharsets.UTF_8));
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write(string);
        } catch (IOException e) {
            log.error("客户端渲染异常：{}", e.getMessage());
        }
        return null;
    }

    /**
     * 是否是Ajax异步请求
     */
    public static boolean isAjaxRequest(HttpServletRequest request) {
        String accept = request.getHeader("accept");
        if (null != accept && accept.indexOf(ContentType.JSON.getValue()) != -1) {
            return true;
        }
        String xRequestedWith = request.getHeader("X-Requested-With");
        if (null != xRequestedWith && xRequestedWith.indexOf("XMLHttpRequest") != -1) {
            return true;
        }
        String uri = request.getRequestURI();
        if (StringUtil.inStringIgnoreCase(uri, ".json", ".xml")) {
            return true;
        }
        String ajax = request.getParameter("__ajax");
        return StringUtil.inStringIgnoreCase(ajax, "json", "xml");
    }

    public static String getRequestPrefix() {
        return getRequestPrefix("/");
    }

    public static String getRequestPrefix(String context) {
        //网络协议
        String networkProtocol = getRequest().getScheme();
        String origin = getRequest().getHeader("Host");
        String address = "";
        if (null == origin) {
            //网络ip
            String ip = getRequest().getServerName();
            //端口号
            int port = getRequest().getServerPort();
            //项目发布名称
            String webApp = getRequest().getContextPath();
            address = networkProtocol + "://" + ip + ":" + port + webApp + context;
        } else {
            address = networkProtocol + "://" + origin + getRequest().getContextPath() + context;
        }

        return address;
    }
}
